package com.wanxi.order.service.impl;


import com.google.common.collect.Maps;

import com.wanxi.domain.code.ResultCode;
import com.wanxi.domain.dto.*;
import com.wanxi.domain.entity.Order;
import com.wanxi.domain.entity.OrderAll;
import com.wanxi.domain.entity.OrderProduct;
import com.wanxi.domain.vo.*;
import com.wanxi.order.mapper.OrderMapper;
import com.wanxi.order.service.OrderService;


import com.wanxi.util.GetTimeNow;
import com.wanxi.util.OrderStatusConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;

/**
 * @Author LiuYuRong
 * @Date 2022/1/4 9:36
 * @Version 1.0
 * @Description
 */
@Service
public class OrderServiceImpl implements OrderService {
    //    列名枚举
    private enum OrderCol {
        status("status"),
        payTime("pay_time"),
        sendTime("send_time"),
        getTime("get_time");
        String col;

        OrderCol(String col) {
            this.col = col;
        }
    }


    @Autowired
    private OrderMapper orderMapper;

    @Transactional
    @Override
    public int payOrder(long id) {
        int amount = orderMapper.selectOrderById(id);
        if (amount != 0) {
//            第三方需要 流水单号，总金额，标题三个必填项，标题暂定为流水单号
            //        调用第三方支付接口，等待返回正确结果，之后再修改订单状态 未付款——>已付款
//            这里假设返回成功，请求参数之类的一切正常

//                获取平台订单下的所有店铺订单
            List<Long> ordersBypid = orderMapper.getOrdersBypid(id);

//            将全部状态设置为已发货
            for (Long orderid :
                    ordersBypid) {
                changeOrderStatus(orderid,OrderStatus.Payed);
            }
            return 1;

        }


        return 0;
    }

    @Override
    public List<OrderVO> getOrders(long roleId, int role, OrderQueryVO queryVO) {

//        验证分页数据是否符合标准,设置分页
        if (queryVO.getPage() < 1) {
            queryVO.setPage(1);
        }
        if (queryVO.getPageSize() < 1) {
            queryVO.setPageSize(10);
        }
        queryVO.setPage((queryVO.getPage() - 1) * queryVO.getPageSize());
//        将roleId回填到queryVO中
        queryVO.setRoleId(roleId);

        List<OrderVO> orderVOList;
        switch (role) {
            case 0:
//                搜索该用户的所有订单
                orderVOList = getOrdersByUserId(roleId,queryVO.getPage(),queryVO.getPageSize());
                break;
            case 1:
//                搜索店家的所有订单，并根据条件进行检索
                orderVOList = getOrdersByShopId(queryVO);
                break;
            case 2:
//                搜索该企业下的所有订单，
                orderVOList = getOrdersByEnterpriseId(roleId,queryVO.getPage(),queryVO.getPageSize());
                break;
            default:
                orderVOList = null;
                break;


        }


        return orderVOList;

    }

    private List<OrderVO> getOrdersByEnterpriseId(Long roleId,int page,int pageSize) {
        return orderMapper.getOrdersByEnterpriseId(roleId,page,pageSize);
    }

    private List<OrderVO> getOrdersByShopId(OrderQueryVO queryVO) {
        List<String> userIdList=null;
        List<String> couponList=null;
        if (queryVO.getUsername()!=null){
          userIdList=  orderMapper.getUserIdByUserName(queryVO.getUsername());
        }
        if (queryVO.getCouponType()!=null){
            couponList=orderMapper.getCouponIdByCouponType(queryVO.getCouponType());
        }
        return orderMapper.getOrdersByShopId(queryVO.getRoleId(),queryVO,userIdList,couponList);


    }


    private List<OrderVO> getOrdersByUserId(Long customerId,int page,int pageSize) {
        return orderMapper.getOrdersByUserId(customerId,page,pageSize);
    }


    @Transactional
    @Override
    public int addOrder(PlaceOrderVO order) {
//        拆分订单到每个门店，根据商品的门店id来拆分出每个门店商品
        List<OrderProductVO> productVOS = order.getProductVOS();
        Map<Long, List<OrderProductVO>> listMap = new HashMap<>();

//        根据门店id拆分出各个门店的订单
        for (OrderProductVO productVO : productVOS) {
            Long shopId = productVO.getShopId();
            if (listMap.containsKey(shopId)) {
                List<OrderProductVO> orderProductVOS = listMap.get(shopId);
                orderProductVOS.add(productVO);
                listMap.put(shopId, orderProductVOS);
            } else {
                List<OrderProductVO> orderProductVOS = new ArrayList<>();
                orderProductVOS.add(productVO);
                listMap.put(shopId, orderProductVOS);
            }
        }
        OrderAll orderAll = new OrderAll();
        orderAll.setAmount(countAmount(productVOS));
        orderAll.setCreateTime(GetTimeNow.getTime());
//        将总订单插入到总订单表中
        orderMapper.insertIntoOrderAll(orderAll);
        long orderAllId = orderAll.getId();


//      将placeOrder包装成Order实体
        Order orderE = new Order();
        orderE.setUser_id(order.getUserId());
        orderE.setCoupon_id(order.getCouponId());
        orderE.setReceiving_address(order.getAddress());
        orderE.setPhone(order.getPhone());
//        下单只能设置状态为0
        orderE.setStatus(OrderStatus.ordered.getStatus());
        orderE.setCreate_time(GetTimeNow.getTime());
        orderE.setUpdate_time(GetTimeNow.getTime());
        orderE.setCreate_user(String.valueOf(order.getUserId()));

//        将订单和订单对应商品插入到对应表中
        listMap.forEach((shopId, vos) -> {
            Order order1 = orderE.myclone();
            BigDecimal amount = countAmount(vos);
            order1.setAmount(amount.toString());
            order1.setOrder_all(orderAllId);
            orderMapper.addOrder(order1);

            OrderProductDTO[] dtos = new OrderProductDTO[vos.size()];
            for (int j = 0; j < dtos.length; j++) {
                dtos[j] = new OrderProductDTO();
            }
            for (int j = 0; j < dtos.length; j++) {
                dtos[j].setSkuId(vos.get(j).getSkuId());
                dtos[j].setOrderId(order1.getId());
                dtos[j].setProductNum(vos.get(j).getProductNum());
                dtos[j].setShopId(shopId);

                orderMapper.addProducts(dtos[j]);
            }

        });

//      返回总订单
        OrderAllVO allVO = new OrderAllVO();
        allVO.setId(orderAll.getId());
        allVO.setAmount(orderAll.getAmount());
        allVO.setCreateTime(orderAll.getCreateTime());
        allVO.setProductVOS(order.getProductVOS());


        return 1;
    }


    @Transactional
    @Override
    public ResultCode changeOrderStatus(long orderId, OrderStatus statusEnum) {
        int status = statusEnum.getStatus();
        int orderStatus = orderMapper.getOrderCol(OrderCol.status.col, orderId);
//        状态插入校验，如果状态是正确的从前到后或者从未付款到取消订单的改变就允许改变，否则不准许
//        并且，在在状态转移时也会对应生成时间
        if (checkStatus(statusEnum, orderStatus)) {
            orderMapper.updateOrder(orderId, OrderCol.status.col, status);
            if (statusEnum == OrderStatus.Payed) {
//                pay的传递值是 总订单id，条件应为order_all=orderId;
                orderMapper.updateOrder(orderId, OrderCol.payTime.col, GetTimeNow.getTime());
            } else if (statusEnum == OrderStatus.send) {
                orderMapper.updateOrder(orderId, OrderCol.sendTime.col, GetTimeNow.getTime());
            } else if (statusEnum == OrderStatus.received) {
                orderMapper.updateOrder(orderId, OrderCol.getTime.col, GetTimeNow.getTime());
            }
            return ResultCode.SUCCESS;

        }
        return ResultCode.FAILED;

    }


    private boolean checkStatus(OrderStatus statusEnum, int orderStatus) {
        OrderStatusConverter converter = new OrderStatusConverter();
        int status = statusEnum.getStatus();
        OrderStatus orderStatusE = converter.convert(orderStatus);

//        如果检索到的orderStatus对应的枚举值为ordered并且statusEnum(要改变的值)为取消订单状态都合法
        if (orderStatusE == OrderStatus.ordered && statusEnum == OrderStatus.handleCanceled)
            return true;
        else if (orderStatusE == OrderStatus.ordered && statusEnum == OrderStatus.autoCanceled)
            return true;
//        正常的状态流转也会成功
        else return orderStatus + 1 == status;


    }


    @Override
    public ResultCode deleteOrder(long orderId) {

        int i = orderMapper.deleteOrderById(orderId);
        if (i == 1) {
            return ResultCode.SUCCESS;
        }
        return ResultCode.FAILED;
    }

    @Override
    public Map<String, Object> beforeSubmitOrder(PlaceOrderVO orderVO) {
//        计算订单总金额
//            格式化金额到两位小数
        NumberFormat money = NumberFormat.getCurrencyInstance();

        Map<String, Object> map = new HashMap<>();
        BigDecimal amount = countAmount(orderVO.getProductVOS());

//        计算使用优惠劵后的实际金额，只有在使用了优惠卷才执行
        if (StringUtils.isEmpty(orderVO.getCouponId())) {
            map.put("amount", money.format(amount).replace("￥", ""));
            return map;
        } else {

            BigDecimal discountAmount = new BigDecimal("0.00");
            CouponDTO coupon = orderMapper.getCouponById(orderVO.getCouponId());
            if (coupon.getDiscount().toString().equals("0.00"))
                discountAmount = amount.subtract(coupon.getCouponMoney());

            else discountAmount = amount.multiply(coupon.getDiscount());
//            只返回优惠后的计算价格
            map.put("amount", money.format(discountAmount).replace("￥", ""));
            return map;
        }
    }


    //    计算订单总额
    private BigDecimal countAmount(List<OrderProductVO> vos) {


        List<Long> skuIdList = new ArrayList<>();
        Map<Long, Integer> skuIdNum = new HashMap<>();
        for (OrderProductVO o :
                vos) {
            skuIdList.add(o.getSkuId());
            skuIdNum.put(o.getSkuId(), o.getProductNum());
        }

//      返回List<SkuIdPrice>类型而不返回LIst<Map>结构，因为类型擦除导致的问题 typecastexception
        List<SkuIdPrice> skuIdPriceList = orderMapper.getPriceBySkuIdList(skuIdList);
        BigDecimal amount = new BigDecimal(0);

        System.out.println(skuIdPriceList);
//        遍历sku_id列表并在skuIdPriceList中寻找和skuId相同map，并得到价格，以此计算出每件商品总额
        for (int i = 0; i < skuIdList.size(); i++) {
//            获得当前skuId
            Long skuid = skuIdList.get(i);
            for (int j = 0; j < skuIdPriceList.size(); j++) {
//                遍历skuId列表，找到list中SkuIdPrice中的skuId为skuid的元素

                if (skuIdPriceList.get(j).getSkuId().equals(skuid)) {
//                    得到价格，并从skuIdNum中得到对应的商品数量
                    BigDecimal price = new BigDecimal(skuIdPriceList.get(j).getSalePrice());
                    BigDecimal count = new BigDecimal(skuIdNum.get(skuid));
//                    求和
                    amount = amount.add(count.multiply(price));
//                    删掉这个元素，提高遍历效率
//                    skuIdPriceList.remove(i);
                    break;
                }
            }

        }
        return amount;

    }


}
